package at.jku.pervasive.gui.action;

import java.awt.event.ActionEvent;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;

import javax.swing.AbstractAction;
import javax.swing.Icon;

import at.jku.pervasive.Application;
import at.jku.pervasive.Helper;
import at.jku.pervasive.Measurement;
import at.jku.pervasive.Position;
import at.jku.pervasive.PositionListener;
import at.jku.pervasive.gui.jformdesigner.RecordingPanel;
import at.jku.pervasive.gui.jformdesigner.TagAssignmentPanel;

public class RecordAction extends AbstractAction implements PositionListener
{

	private Application application;
	private boolean recording;
	private Icon startRecordIcon, stopRecordingIcon;

	private LinkedList<Position> positions;
	private Date startDate, endDate;
	private final RecordingPanel recordingPanel;

	private DateFormat dateFormat;
	private final TagAssignmentPanel tagAssignmentPanel;

	private class TimeDiffThread extends Thread
	{
		
		public TimeDiffThread()
		{
			super();
		}

		public void run()
		{
			while (recording)
			{
				// update info message about this recording
				long timeDiffInMillis = Helper.timeDiff(RecordAction.this.startDate.getTime());
				tmpDate.setTime(timeDiffInMillis);

				String info = String.format("%d positions (%s)", positions.size(), dateFormat.format(tmpDate));
				RecordAction.this.recordingPanel.setInfoText(info);

				try
				{
					Thread.sleep(500);
				} catch (InterruptedException e)
				{
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	public RecordAction(RecordingPanel recordingPanel, TagAssignmentPanel tagAssignmentPanel)
	{
		super();

		this.recordingPanel = recordingPanel;
		this.tagAssignmentPanel = tagAssignmentPanel;
		
		this.positions = new LinkedList<Position>();

		this.dateFormat = new SimpleDateFormat("mm:ss");

		application = Application.getInstance();
		application.addPositionListener(this);

		// URL startRecordingUrl =
		// RecordAction.class.getResource("/icons/start-recording.png");
		// startRecordIcon = new ImageIcon(startRecordingUrl);
		//
		// URL stopRecordUrl =
		// RecordAction.class.getResource("/icons/stop-recording.png");
		// stopRecordingIcon = new ImageIcon(stopRecordUrl);
		//
		// putValue(SMALL_ICON, startRecordIcon);

		putValue(NAME, "Start recording");
	}

	public void actionPerformed(ActionEvent e)
	{
		recording = !recording;
		if (recording)
		{
			// start recording
			putValue(NAME, "Stop recording");
			this.positions.clear();
			this.startDate = Helper.now();

			this.recordingPanel.clearAllTagPositions();

			new TimeDiffThread().start();
		}
		else
		{
			// recording stopped; so save measured positions
			putValue(NAME, "Start recording");

			this.endDate = Helper.now();
			// get the description
			String description = this.recordingPanel.getDescription();

			Measurement measurement = new Measurement(description, startDate, endDate);
			
			// set the assigned tags
			measurement.setBackTagId(this.tagAssignmentPanel.getBackTagId());
			measurement.setChestTagId(this.tagAssignmentPanel.getChestTagId());
			measurement.setLeftTagId(this.tagAssignmentPanel.getLeftTagId());
			measurement.setRightTagId(this.tagAssignmentPanel.getRightTagId());
			
			measurement.setPositions(this.positions.toArray(new Position[this.positions.size()]));
			application.saveMeasurement(measurement);
		}
	}

	public void positionChanged(Position newPosition)
	{
		String tagId = newPosition.getId();
		if (recording && application.isTracingTag(tagId))
		{
			this.positions.add(newPosition);
			this.recordingPanel.addTagPosition(newPosition);
		}
	}

	private Date tmpDate = new Date();
}
